import { computed, defineComponent, h, markRaw, reactive } from 'vue'
import ItemNode from '../../ItemNode/ItemNode'
import {
  ElDatePicker,
  ElFormItem,
  ElInput,
  ElOption,
  ElRadioButton,
  ElRadioGroup,
  ElSelect,
  ElText
} from 'element-plus'
import classes from '../../ItemNode/ItemNode.module.css'
import { state } from '../../store/store.js'
import { generateRule } from '../../utils'
import Tip from '../../panel/Tip.vue'
import CodeEditor from '../../panel/CodeEditor.vue'

export default class NDatePicker extends ItemNode {
  isNDatePicker = true
  isFormNode = true

  constructor(node?: NDatePicker) {
    super(node)

    if (!node) {
      this.path = './components/NDatePicker/NDatePicker.tsx'
      this.name = '日期时间选择器'

      this.props.field = `${NDatePicker.name.replace(/^N(\w)/, (match, p1) => p1.toLowerCase())}_${this.uuid.split('-').at(0)}`
      this.props.type = 'datetime'
      this.props.value = ''
      this.props.label = ''
      this.props.placeholder = '请选择'
      this.props.ruleMessage = '请正确选择'
      this.props.ruleType = 'none'
      this.props.changeFn = `function (value) {\n  value\n}`
    }

    const rulesOptions = reactive([
      {
        label: '无验证',
        value: 'none'
      },
      {
        label: '默认验证',
        value: 'default'
      }
    ])

    const pComponent = this.component
    this.component = markRaw(
      defineComponent(
        (props) => {
          const rule = computed(() => generateRule(this.props.ruleType, this.props.ruleMessage))

          const onChange = (value) => {
            if (state) eval(`(${this.props.changeFn})`)(value)
          }

          onChange(this.props.value)

          return () => (
            <pComponent>
              <ElFormItem label={this.props.label} prop={this.props.field} rules={rule.value}>
                {/* ElDatePicker组件类型缺少teleported不能通过ts验证，用渲染函数 */}
                {() =>
                  h(ElDatePicker, {
                    type: this.props.type,
                    placeholder: this.props.placeholder,
                    teleported: false,
                    modelValue: this.props.value,
                    'onUpdate:modelValue': (value) => (this.props.value = value),
                    onChange
                  })
                }
              </ElFormItem>
            </pComponent>
          )
        },
        {
          name: 'NDatePicker'
        }
      )
    )

    const pView = this.view
    this.view = markRaw(
      defineComponent((props) => {
        return () => (
          <pView>
            <this.component style={{ transform: 'scale(0.4)' }}></this.component>
          </pView>
        )
      })
    )

    const pParams = this.params
    this.params = markRaw(
      defineComponent(() => {
        return () => (
          <pParams>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                字段
              </ElText>
              <div class={classes['params-item-content']}>
                <ElInput v-model={this.props.field} size="small"></ElInput>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                类型
              </ElText>
              <div class={classes['params-item-content']}>
                <ElRadioGroup
                  size="small"
                  modelValue={this.props.type}
                  onUpdate:modelValue={(v) => {
                    this.props.value = v === 'datetimerange' || v === 'daterange' ? [] : ''
                    this.props.type = v
                  }}
                >
                  <ElRadioButton value="year" label="年"></ElRadioButton>
                  <ElRadioButton value="month" label="月"></ElRadioButton>
                  <ElRadioButton value="date" label="日期"></ElRadioButton>
                  <ElRadioButton value="datetime" label="日期时间"></ElRadioButton>
                  <ElRadioButton value="week" label="周"></ElRadioButton>
                  <ElRadioButton value="datetimerange" label="日期时间范围"></ElRadioButton>
                  <ElRadioButton value="daterange" label="日期范围"></ElRadioButton>
                </ElRadioGroup>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                标签
              </ElText>
              <div class={classes['params-item-content']}>
                <ElInput v-model={this.props.label} size="small"></ElInput>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                占位文本
              </ElText>
              <div class={classes['params-item-content']}>
                <ElInput v-model={this.props.placeholder} size="small"></ElInput>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                验证规则
              </ElText>
              <div class={classes['params-item-content']}>
                <ElSelect v-model={this.props.ruleType} size="small" teleported={false}>
                  {() =>
                    rulesOptions.map((item) => (
                      <ElOption key={item.value} label={item.label} value={item.value}></ElOption>
                    ))
                  }
                </ElSelect>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                验证消息
              </ElText>
              <div class={classes['params-item-content']}>
                <ElInput v-model={this.props.ruleMessage} size="small"></ElInput>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                值变化处理函数
                <Tip content={'值变化后调用；可访问全局状态变量state，value：组件的值'}></Tip>
              </ElText>
              <div class={classes['params-item-content']}>
                <CodeEditor
                  modelValue={this.props.changeFn}
                  onUpdate:modelValue={(v) => (this.props.changeFn = v || '')}
                ></CodeEditor>
              </div>
            </div>
          </pParams>
        )
      })
    )
  }

  toVue(): SfcObj {
    const sfcObj = super.toVue()
    const name = sfcObj.name
    const [uuid0, uuid1] = this.uuid.split('-')
    const valueVar = `${name}_${uuid0}_value`
    const ruleVar = `${name}_${uuid0}_rule`
    const onChangeVar = `${name}_${uuid0}_onChange`

    const ruleStr = JSON.stringify(generateRule(this.props.ruleType, this.props.ruleMessage))

    sfcObj.imports = {
      ...sfcObj.imports,
      vue: {
        ref: 'ref'
      },
      ['element-plus']: {
        ElFormItem: 'ElFormItem',
        ElDatePicker: 'ElDatePicker'
      }
    }

    sfcObj.script = `
${sfcObj.script}
const ${valueVar} = ref()
const ${ruleVar} = ref(${ruleStr})
const ${onChangeVar} = (value) => {
  (${this.props.changeFn})(value)
}
${onChangeVar}(${typeof this.props.value == 'string' ? `'${this.props.value}'` : this.props.value})
      `

    sfcObj.template = sfcObj.template.replace(
      '<slot></slot>',
      `
  <ElFormItem label="${this.props.label}" prop="${this.props.field}" :rules="${ruleVar}">
    <ElDatePicker
      type="${this.props.type}"
      :teleported="false"
      placeholder="${this.props.placeholder}"
      v-model="${valueVar}"
      @change="${onChangeVar}"
    ></ElDatePicker>
  </ElFormItem>
      `
    )

    return sfcObj
  }
}
